home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Icon 8.1 / msm-1 / icont.sit / mktoktab.icn < prev    next >
Encoding:
Text File  |  1992-09-19  |  6.5 KB  |  203 lines  |  [TEXT/MPS ]

  1. # Build token and operator tables ("toktab.c" and "optab.c")
  2. # from token description file "tokens.txt" and skeleton operator
  3. # state tables in "optab.txt".
  4.  
  5. global token, tokval, bflag, eflag, head, oper, tail, count
  6. global restable, opertable, flagtable
  7. global tokfile, opfile, toktab, optab
  8.  
  9. procedure tokpat()
  10.    if match("#") then return token := tab(0)
  11.    if tab(many(' \t')) & (token := tab(upto(' \t'))) &
  12.       tab(many(' \t')) & (tokval := (tab(upto(' \t') | 0)))
  13.    then return (tab(upto('b')) & (bflag := move(1))) | (bflag := "") &
  14.       ((tab(upto('e')) & (eflag := move(1))) | (eflag := "")) & pos(0)
  15. end
  16.  
  17. procedure operpat()
  18.    return (head := tab(upto('['))) & ="[   ]" &
  19.       (tail := (tab(upto('"')) || move(1) ||
  20.       (oper := tab(upto('"'))) || move(1) || tab(0)))
  21. end
  22.  
  23. procedure main()
  24.    local line, letter, lastletter
  25.    restable := table()
  26.    opertable := table()
  27.    flagtable := table("")
  28.    flagtable[""] := "0,"
  29.    flagtable["b"] := "Beginner,"
  30.    flagtable["e"] := "Ender,"
  31.    flagtable["be"] := "Beginner+Ender,"
  32.    count := 0
  33.    lastletter := ""
  34.  
  35.    tokfile := open("tokens.txt") | stop("unable to open \"tokens.txt\"")
  36.    opfile := open("optab.txt") | stop("unable to open \"optab.txt\"")
  37.    toktab := open("toktab.c","w")
  38.    optab := open("optab.c","w")
  39.  
  40. # Skip the first few (non-informative) lines of "tokens.txt"
  41.  
  42.    garbage()
  43.  
  44. # Output header for "toktab.c"
  45.    write(toktab,"#include \"../h/gsupport.h\"")
  46.    write(toktab,"#include \"tproto.h\"")
  47.    write(toktab,"#include \"trans.h\"")
  48.    write(toktab,"#include \"tlex.h\"")
  49.    write(toktab,"#include \"token.h\"")
  50.    write(toktab)
  51.    write(toktab,"/*")
  52.    write(toktab," * Token table - contains an entry for each token type")
  53.    write(toktab," * with printable name of token, token type, and flags")
  54.    write(toktab," * for semicolon insertion.")
  55.    write(toktab," */")
  56.    write(toktab)
  57.    write(toktab,"struct toktab toktab[] = {")
  58.    write(toktab,"/*  token\t\ttoken type\tflags */")
  59.    write(toktab)
  60.    write(toktab,"   /* primitives */")
  61.  
  62. # Read primitive tokens and output to "toktab.c"
  63.  
  64.    repeat {
  65.       write(toktab,makeline(token,tokval,bflag || eflag,count))
  66.       count +:= 1
  67.       line := read(tokfile) | stop("premature end-of-file")
  68.       line ? tokpat() | break
  69.          }
  70.  
  71. # Skip some more garbage lines
  72.  
  73.    garbage()
  74.  
  75. # Output some more comments
  76.  
  77.    write(toktab)
  78.    write(toktab,"   /* reserved words */")
  79.  
  80. # Read in reserved words, output them,
  81. # and build table of first letters.
  82.  
  83.    repeat {
  84.       write(toktab,makeline(token,tokval,bflag || eflag,count))
  85.       letter := token[1]
  86.       if letter ~== lastletter then {
  87.          lastletter := letter
  88.          restable[letter] := count
  89.         }
  90.    count +:= 1
  91.    line := read(tokfile) | stop("premature end-of-file")
  92.    if line ? tokpat() then next else break
  93.    }
  94.  
  95. # Skip more garbage
  96.  
  97.    garbage()
  98.  
  99. # Another comment
  100.  
  101.    write(toktab)
  102.    write(toktab,"   /* operators */")
  103.  
  104. # Read in operators, output them, and build table
  105.  
  106. repeat {
  107.    write(toktab,makeline(token,tokval,bflag || eflag,count))
  108.    opertable[token] := count
  109.    if not match("#",token) then count +:= 1
  110.    line := read(tokfile) | stop("premature end-of-file")
  111.    line ? tokpat() | break
  112.    }
  113.    eof()
  114. end
  115.  
  116. procedure eof()    # output end of token table and reserveed word first-letter index.
  117.    local line
  118.    write(toktab,makeline("end-of-file","0","",""))
  119.    write(toktab,"   };")
  120.    write(toktab)
  121.    write(toktab,"/*")
  122.    write(toktab," * restab[c] points to the first reserved word in toktab which")
  123.    write(toktab," * begins with the letter c.")
  124.    write(toktab," */")
  125.    write(toktab)
  126.    write(toktab,"#if !EBCDIC")
  127.    write(toktab,"struct toktab *restab[] = {")
  128.    write(toktab,makeres("abcd"))
  129.    write(toktab,makeres("efgh"))
  130.    write(toktab,makeres("ijkl"))
  131.    write(toktab,makeres("mnop"))
  132.    write(toktab,makeres("qrst"))
  133.    write(toktab,makeres("uvwx"))
  134.    write(toktab,makeres("yz"))
  135.    write(toktab,"   };")
  136.  
  137. #  This really is faked -- need fixing if anything changes.
  138.    write(toktab,"#else                    /* !EBCDIC */")
  139.    write(toktab, "struct toktab *restab[] = {")
  140.    write(toktab, "               NULL       ,&toktab[ 6],&toktab[ 8],    /* 81-83  abc */")
  141.    write(toktab, "   &toktab[10],&toktab[12],&toktab[15],&toktab[16],    /* 84-87 defg */")
  142.    write(toktab, "    NULL       ,&toktab[17],NULL       ,NULL      ,    /* 88-8B hi.. */")
  143.    write(toktab, "    NULL       ,NULL      ,NULL       ,NULL       ,    /* 8C-8F .... */")
  144.    write(toktab, "")
  145.    write(toktab, "   NULL       ,NULL      ,NULL       ,&toktab[19],    /* 90-93 .jkl */")
  146.    write(toktab, "   NULL       ,&toktab[21],&toktab[23],&toktab[24],    /* 94-97 mnop */")
  147.    write(toktab, "   NULL       ,&toktab[25],NULL       ,NULL      ,    /* 98-9B qr.. */")
  148.    write(toktab, "   NULL       ,NULL      ,NULL       ,NULL       ,    /* 9C-9F .... */")
  149.    write(toktab, "")
  150.    write(toktab, "   NULL       ,NULL      ,&toktab[28],&toktab[30],    /* A0-A3 ..st */")
  151.    write(toktab, "   &toktab[32],NULL      ,&toktab[33],NULL,           /* A4-A7 uvwx */")
  152.    write(toktab, "   NULL       ,NULL      ,                            /* A8-AB yz   */")
  153.    write(toktab, "   };")
  154.    write(toktab, "#endif                                  /* !EBCDIC */")
  155.  
  156.    close(toktab)
  157.  
  158. # Read through operator state table skeleton, inserting
  159. # token numbers for operators.
  160.  
  161.    repeat {
  162.       while line := read(opfile) | break break do {
  163.          if line ? operpat() then break
  164.          else write(optab,line)
  165.          }
  166.       if /opertable[oper] then write(&errout,"no entry for",oper)
  167.       else {
  168. #        write(&errout,"oper=",oper,"; index=",opertable[oper])
  169.          write(optab,head,"[",right(opertable[oper],3),"]",tail)
  170.          }
  171.       }
  172. end
  173.  
  174. procedure makeline(token,tokval,flag,count)    # build an output line for token table.
  175.    local line
  176.    if match("#",token) then return token
  177.    line := left("   \"" || token || "\",",22) || left(tokval ||  ",",15)
  178.    flag := flagtable[flag]
  179.    if count ~=== "" then flag := left(flag,19)
  180.    line ||:= flag
  181.    if count ~=== "" then line ||:= "/* " || right(count,3) || " */"
  182.    return line
  183. end
  184.  
  185. procedure makeres(lets)    # build an output line for reserved word index.
  186.    local let, letters, line
  187.    line := "   "
  188.    letters := lets
  189.    every let := !lets do
  190.       if \restable[let] then {
  191. #        write(&errout,"let=",let,"; index=",restable[let])
  192.          line ||:= "&toktab[" || right(restable[let],2) || "], "
  193.          }
  194.       else line ||:= "NULL,        "
  195.    return left(line,55) || "/* " || letters || " */"
  196. end
  197.  
  198. procedure garbage()
  199.    local line
  200.    while line := read(tokfile) | stop("premature end-of-file") do
  201.       if line ? tokpat() then return
  202. end
  203.